package com.bdqn.ch01.SZ.sz1;

import com.bdqn.ch01.Sl.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * TestJavaBean
 *
 * @aurhor Administrator  whs
 * @since 2024/6/27
 */
public class TestJavaBean {

    public static void main(String[] args) {

        // 获取 Class 实例
        Class clazz = Person.class;

        String fullName = clazz.getSimpleName(); //获取类的完全限定名称（包名+类名）

        String simpleName = clazz.getName(); //返回类名
        System.out.println("==========类的基本信息展示===========");
        System.out.println("以下是 "+simpleName+" 类的基本信息");
        System.out.println("------------------------");
        System.out.println("类名: "+fullName);
        System.out.println("------------------------");


        Package pkg = clazz.getPackage(); // 得到包类
        System.out.println( fullName + "定义在： "+pkg.getName()+ " 包中");
        System.out.println("------------------------");

        Class superClass = clazz.getSuperclass(); // 获取父类
        System.out.println(fullName + " 类的父类是: "+superClass.getName());
        System.out.println("------------------------");

        Class[] interfaces = clazz.getInterfaces(); // 实现的接口
        System.out.println( fullName + " 类所实现的接口: ");
        for (Class anInterface : interfaces) {
            System.out.println("\t" + anInterface.getName());
        }
        System.out.println("------------------------");

        int modifier = clazz.getModifiers(); // 获取类的访问修饰符

        System.out.print(fullName + " 的修饰符是：");
        if ((modifier & Modifier.PUBLIC) == Modifier.PUBLIC) {
            System.out.println("public ");
        }else if ((modifier & Modifier.PROTECTED) == Modifier.PROTECTED){
            System.out.println("protected ");
        }else if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) {
            System.out.println("private ");
        }else {
            System.out.println("default(package) ");
        }
        
        if ((modifier & Modifier.FINAL)== Modifier.FINAL){
            System.out.println(" 这个类是 final 的");
        }
        if ((modifier & Modifier.ABSTRACT)== Modifier.ABSTRACT){
            System.out.println(" 这个类是 abstract 的");
        }
        if ((modifier & Modifier.STATIC)== Modifier.STATIC){
            System.out.println(" 这个类是 static 的");
        }
        if ((modifier & Modifier.SYNCHRONIZED)== Modifier.SYNCHRONIZED){
            System.out.println(" 这个类是 synchronized 的");
        }
        System.out.println("\n\n");


        Constructor[] cons = Person.class.getDeclaredConstructors();
        //构造方法的一些信息
        System.out.println("===========构造方法展示============");
        for (Constructor con : cons) {

            System.out.print("访问修饰符：");   // public
            int modifiers = con.getModifiers();

            // 判断该构造方法的访问修饰符
            if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC) {    // 访问修饰符 : protected
                System.out.print("public ");
            }else if ((modifiers & Modifier.PROTECTED) == Modifier.PROTECTED){
                System.out.print("protected ");
            }else if ((modifiers & Modifier.PRIVATE) == Modifier.PRIVATE) {
                System.out.print("private ");
            }else {
                System.out.print("default(package) ");
            }
            System.out.println("\n------------------------");


            // 获取构造方法的参数列表
            Class[] params = con.getParameterTypes();
            if (params.length == 0 ){                        // 该构造方法没有参数
                System.out.print("该构造方法没有参数");

            }else {
                System.out.print("该构造方法的参数列表为：[");   // 该构造方法的参数列表为：[java.lang.String, java.lang.String, ]
                for (int i = 0; i < params.length; i++) {
                    if (i != 0){
                        System.out.print(params[i].getName());
                        System.out.print(", ");
                    }
                }
                System.out.println("]");
                System.out.println("---------------------------");
            }

        }

        System.out.println("\n\n");


        Field[] fields = Person.class.getDeclaredFields();
        //展示一些属性
        System.out.println("=========属性展示=========");
        for (Field field : fields){
            System.out.println("属性名：" + field.getName());     // 属性名：name
            System.out.println("类型：" + field.getType().getName()); // 类型：java.lang.String
            System.out.print("访问修饰符：" );   // private
            int modifiers = field.getModifiers();

            // 判断属性的访问修饰符
            if ((modifiers & Modifier.PUBLIC)== Modifier.PUBLIC){
                System.out.println("public");
            }else if ((modifiers & Modifier.PROTECTED)== Modifier.PROTECTED){
                System.out.println("protected");
            }else if ((modifiers & Modifier.PRIVATE)== Modifier.PRIVATE){
                System.out.println("private");
            }else {
                System.out.println("default(package)");
            }

            // 判断属性是否有 static 修饰符
            if ((modifiers & Modifier.STATIC)== Modifier.STATIC){
                System.out.println("这是一个静态属性");
            }
            //判断该属性是否有 final 属性
            if ((modifiers & Modifier.FINAL)== Modifier.FINAL){
                System.out.println("这是一个final属性");
            }
            System.out.println("-----------------------------------");

        }


        Method[] methodss = Person.class.getDeclaredMethods();
        // 展示方法的一些属性
        System.out.println("\n\n==========方法展示============");
        for (Method method : methodss) {
            System.out.println("方法名：" + method.getName());
            System.out.println("方法值返回类型：" + method.getReturnType().getName());

            // 获取方法的参数列表
            Class[] params = method.getParameterTypes();
            if (params.length == 0 ){
                System.out.println("该方法没有参数\n");
            }else {
                System.out.print("该参数的参数列表为：[");
                for (int i = 0; i < params.length; i++) {
                    if (i !=0){
                        System.out.print(",");
                    }
                    System.out.print(params[i].getName());
                }
                System.out.print("]\n");
                System.out.println();
            }
            System.out.print("访问修饰符：");
            int modifierss = method.getModifiers();

            // 判断该方法的访问修饰符
            if ((modifierss & Modifier.PUBLIC)== Modifier.PUBLIC){
                System.out.println("public");
            }else if ((modifierss & Modifier.PROTECTED)== Modifier.PROTECTED){
                System.out.println("protected");
            }else if ((modifierss & Modifier.PRIVATE)== Modifier.PRIVATE){
                System.out.println("private");
            }else {
                System.out.println("default(package)");
            }

            // 判断该方法是否有 static 修饰符
            if ((modifierss & Modifier.STATIC) == Modifier.STATIC){
                System.out.println("这是一个静态方法");
            }
            // 判断该方法是否有 final 修饰符
            if ((modifierss & Modifier.FINAL) == Modifier.FINAL){
                System.out.println("这是一个final方法");
            }
            // 判断该方法是否有 abstract 修饰符
            if ((modifierss & Modifier.ABSTRACT) == Modifier.ABSTRACT){
                System.out.println("这是一个抽象方法 ");
            }
            // 判断该方法是否有 synchronized 修饰符
            if ((modifierss & Modifier.SYNCHRONIZED) == Modifier.SYNCHRONIZED){
                System.out.println("这是一个同步方法");
            }


            // 获取方法所属的类或接口的Class 实例
            Class declaringClass = method.getDeclaringClass();
            System.out.println("声明方法在："+declaringClass.getName()+" 中");

            //获取方法抛出的异常类型，即 throws 子句中声明的异常
            Class[] exceptions = method.getExceptionTypes();
            if (exceptions.length > 0){
                System.out.print("该方法抛出的异常有：[");
                for (int i = 0; i < exceptions.length; i++) {
                    if (i!=0){
                        System.out.print(",");
                    }
                    System.out.print(exceptions[i].getName());
                }
                System.out.print("]");
            }
            System.out.println("--------------------------------------------");
        }



    }
}
